package mapred.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public abstract class OrderedConfiguration<K, V> implements Configurable<K, V> {

    private Map<K, V> map;
    
    private String entryDelim;

    private K[] keySet;
    
    public OrderedConfiguration(String s, K[] keySet, String entryDelim) {
        this.map = new HashMap<K, V>();
        this.keySet = keySet;
        this.entryDelim = entryDelim;
        
        decode(s);
    }
    
    private void decode(String s) {
        if (s != null) {
            String[] ts = s.split(this.entryDelim);
            for (int i = 0; i < ts.length; ++i) {
                this.set(keySet[i], decodeValue(ts[i]));
            }
        }
    }

    @Override
    public boolean contains(K key) {
        return this.map.containsKey(key);
    }

    @Override
    public V get(K key) {
        return this.map.get(key);
    }

    @Override
    public void remove(K key) {
        this.map.remove(key);
    }

    @Override
    public void set(K key, V value) {
        this.map.put(key, value);
    }

    @Override
    public int size() {
        return this.map.size();
    }

    @Override
    public Iterator<K> iterator() {
        return map.keySet().iterator();
    }

    @Override
    public String toString() {
        if (this.size() == 0) {
            return "";
        } else {
            StringBuilder sb = new StringBuilder();
            for (K key : this) {
                sb.append(this.entryDelim);
                sb.append(encodeValue(this.get(key)));
            }
            return sb.substring(this.entryDelim.length());
        }
    }
    
    protected abstract String encodeValue(V value);

    protected abstract V decodeValue(String strValue);

}
